﻿using System.Collections.Generic;
using System.IO;

namespace Conv.MnistReader
{
    public class LableReader
    {
        private uint magicNumber;
        private List<byte> _labels;
        private static int _currentLabel = 0;
        public uint ImageCount { get; private set; }
        public LableReader(string fileName)
        {
            FileInfo f = new FileInfo(fileName);
            using (BinaryReader br = new BinaryReader(f.OpenRead()))
            {
                magicNumber = Crunch(br.ReadUInt32());
                ImageCount= Crunch(br.ReadUInt32());
                _labels = new List<byte>((int) ImageCount);
                for (int i = 0; i < ImageCount; i++)
                {
                    _labels.Add(br.ReadByte());
                }
            }
        }
        public void NewEpoh()
        {
            _currentLabel = 0;
        }
        public byte GetLabel()
        {
            return _labels[_currentLabel++];
        }
        private uint Crunch(uint x)
        {
            //x = (x & 0x55555555) << 1 | (x & 0xAAAAAAAA) >> 1;
            //x = (x & 0x33333333) << 2 | (x & 0xCCCCCCCC) >> 2;
            //x = (x & 0x0F0F0F0F) << 4 | (x & 0xF0F0F0F0) >> 4;
            //x = (x & 0x00FF00FF) << 8 | (x & 0xFF00FF00) >> 8;
            //x = (x & 0x0000FFFF) << 16 | (x & 0xFFFF0000) >> 16;
            //return x;
            //k=31 for all bite reverse in word
            //k=24  for byte reverse
            int k = 7;//reverse bites in every byte, bytes not changes
            if ((k & 1) == 0) x = (x & 0x55555555) << 1 | (x & 0xAAAAAAAA) >> 1;
            if ((k & 2) == 0) x = (x & 0x33333333) << 2 | (x & 0xCCCCCCCC) >> 2;
            if ((k & 4) == 0) x = (x & 0x0F0F0F0F) << 4 | (x & 0xF0F0F0F0) >> 4;
            if ((k & 8) == 0) x = (x & 0x00FF00FF) << 8 | (x & 0xFF00FF00) >> 8;
            if ((k & 16) == 0) x = (x & 0x0000FFFF) << 16 | (x & 0xFFFF0000) >> 16;
            return x;
        }
    }
}